using AutoMapper;
using ClosedXML.Excel;
using MediatR;
using RBAC.Domain.MaterialManage;
using RBAC.ErrorCode;
using RBAC.Interstructrue.Base;
using RBAC.Write.Api.Application.Command.ERP.MaterialFile;
using System.Data;

namespace RBAC.Write.Api.Application.Handler.ERP.MaterialFile
{
    /// <summary>
    /// 导出物料分类处理器
    /// </summary>
    public class ExportMaterTypeHandler : IRequestHandler<ExportMaterTypeCommand, APIResult<byte[]>>
    {
        private readonly IBaseRepository<MaterType> materTypeRepository;
        private readonly ILogger<ExportMaterTypeHandler> logger;
        private readonly IMapper mapper;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="materTypeRepository">物料分类仓储</param>
        /// <param name="logger">日志记录器</param>
        /// <param name="mapper">对象映射器</param>
        public ExportMaterTypeHandler(
            IBaseRepository<MaterType> materTypeRepository,
            ILogger<ExportMaterTypeHandler> logger,
            IMapper mapper)
        {
            this.materTypeRepository = materTypeRepository;
            this.logger = logger;
            this.mapper = mapper;
        }

        /// <summary>
        /// 处理导出物料分类请求
        /// </summary>
        /// <param name="request">导出请求</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>Excel文件字节数组</returns>
        public Task<APIResult<byte[]>> Handle(ExportMaterTypeCommand request, CancellationToken cancellationToken)
        {
            APIResult<byte[]> result = new APIResult<byte[]>();

            try
            {
                logger.LogInformation("开始导出物料分类数据");

                // 查询所有未删除的物料分类数据
                var sql = @"SELECT 
                            mt.Id,
                            mt.TypeCode AS 分类编码,
                            mt.TypeName AS 分类名称,
                            mt.Unit AS 计量单位,
                            CASE mt.Status 
                                WHEN 1 THEN '启用' 
                                WHEN 0 THEN '禁用' 
                                ELSE '未知' 
                            END AS 状态,
                            mt.Lenght AS 流水号长度,
                            mt.SupplyMode AS 供应方式,
                            IFNULL(parent.TypeName, '顶级分类') AS 上级分类,
                            mt.CreateTime AS 创建时间,
                            mt.CreateUser AS 创建人
                        FROM MaterType mt
                        LEFT JOIN MaterType parent ON mt.ParentId = parent.Id AND parent.IsDeleted = 0
                        WHERE mt.IsDeleted = 0
                        ORDER BY mt.Id";

                var data = materTypeRepository.Query<MaterTypeExportDto>(sql);

                if (data == null || !data.Any())
                {
                    result.Code = APIEnums.Error;
                    result.Msg = "没有可导出的物料分类数据";
                    return Task.FromResult(result);
                }

                logger.LogInformation("共查询到{Count}条物料分类数据", data.Count());

                // 创建DataTable
                DataTable dt = new DataTable("物料分类");
                dt.Columns.Add("分类编码", typeof(string));
                dt.Columns.Add("分类名称", typeof(string));
                dt.Columns.Add("计量单位", typeof(string));
                dt.Columns.Add("状态", typeof(string));
                dt.Columns.Add("流水号长度", typeof(int));
                dt.Columns.Add("供应方式", typeof(string));
                dt.Columns.Add("上级分类", typeof(string));
                dt.Columns.Add("创建时间", typeof(string));
                dt.Columns.Add("创建人", typeof(string));

                // 填充数据
                foreach (var item in data)
                {
                    DataRow row = dt.NewRow();
                    row["分类编码"] = item.分类编码 ?? "";
                    row["分类名称"] = item.分类名称 ?? "";
                    row["计量单位"] = item.计量单位 ?? "";
                    row["状态"] = item.状态 ?? "";
                    row["流水号长度"] = item.流水号长度 ?? 4;
                    row["供应方式"] = item.供应方式 ?? "";
                    row["上级分类"] = item.上级分类 ?? "";
                    row["创建时间"] = item.创建时间?.ToString("yyyy-MM-dd HH:mm:ss") ?? "";
                    row["创建人"] = item.创建人 ?? "";
                    dt.Rows.Add(row);
                }

                // 导出为Excel
                byte[] fileBytes = ExportToExcel(dt);

                result.Code = APIEnums.Success;
                result.Msg = "物料分类数据导出成功";
                result.Data = fileBytes;

                logger.LogInformation("物料分类数据导出成功，共导出{Count}条记录", data.Count());
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "物料分类数据导出失败：{Message}", ex.Message);
                result.Code = APIEnums.Error;
                result.Msg = "导出物料分类数据失败：" + ex.Message;
            }

            return Task.FromResult(result);
        }

        /// <summary>
        /// 将DataTable导出为Excel字节数组
        /// </summary>
        /// <param name="dataTable">数据表</param>
        /// <returns>Excel文件字节数组</returns>
        private byte[] ExportToExcel(DataTable dataTable)
        {
            using (var workbook = new XLWorkbook())
            {
                var worksheet = workbook.Worksheets.Add(dataTable);

                // 设置表头样式
                var headerRow = worksheet.Row(1);
                headerRow.Style.Font.Bold = true;
                headerRow.Style.Font.FontColor = XLColor.White;
                headerRow.Style.Fill.BackgroundColor = XLColor.CornflowerBlue;
                headerRow.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;

                // 自动调整列宽
                worksheet.Columns().AdjustToContents();

                // 设置边框
                worksheet.RangeUsed().Style.Border.OutsideBorder = XLBorderStyleValues.Thin;
                worksheet.RangeUsed().Style.Border.InsideBorder = XLBorderStyleValues.Thin;

                // 设置数据格式
                for (int i = 2; i <= worksheet.RowsUsed().Count(); i++)
                {
                    var row = worksheet.Row(i);
                    row.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Left;
                }

                using (var memoryStream = new MemoryStream())
                {
                    workbook.SaveAs(memoryStream);
                    return memoryStream.ToArray();
                }
            }
        }
    }

    /// <summary>
    /// 物料分类导出DTO
    /// </summary>
    public class MaterTypeExportDto
    {
        public long Id { get; set; }
        public string? 分类编码 { get; set; }
        public string? 分类名称 { get; set; }
        public string? 计量单位 { get; set; }
        public string? 状态 { get; set; }
        public int? 流水号长度 { get; set; }
        public string? 供应方式 { get; set; }
        public string? 上级分类 { get; set; }
        public DateTime? 创建时间 { get; set; }
        public string? 创建人 { get; set; }
    }
}